package org.example.springboot.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import org.example.springboot.entity.Book;
import org.example.springboot.entity.BookCategory;
import org.example.springboot.exception.ServiceException;
import org.example.springboot.mapper.BookCategoryMapper;
import org.example.springboot.mapper.BookMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 图书分类服务类
 */
@Service
public class BookCategoryService {
    @Resource
    private BookCategoryMapper bookCategoryMapper;
    
    @Resource
    private BookMapper bookMapper;
    
    /**
     * 获取所有分类
     * @return 分类列表
     */
    public List<BookCategory> getAllCategories() {
        return bookCategoryMapper.selectList(new LambdaQueryWrapper<BookCategory>()
                .orderByAsc(BookCategory::getSort));
    }
    
    /**
     * 获取分类树结构
     * @return 分类树结构
     */
    public List<BookCategory> getCategoryTree() {
        List<BookCategory> allCategories = getAllCategories();
        
        // 按照父ID分组
        Map<Long, List<BookCategory>> parentMap = allCategories.stream()
                .collect(Collectors.groupingBy(category -> 
                    category.getParentId() == null ? 0L : category.getParentId()));
        
        // 构建树结构
        List<BookCategory> rootCategories = parentMap.getOrDefault(0L, new ArrayList<>());
        rootCategories.forEach(root -> buildCategoryTree(root, parentMap));
        
        return rootCategories;
    }
    
    /**
     * 递归构建分类树
     * @param parent 父节点
     * @param parentMap 按父ID分组的分类Map
     */
    private void buildCategoryTree(BookCategory parent, Map<Long, List<BookCategory>> parentMap) {
        List<BookCategory> children = parentMap.getOrDefault(parent.getId(), new ArrayList<>());
        parent.setChildren(children);
        
        // 递归处理子节点
        children.forEach(child -> buildCategoryTree(child, parentMap));
    }
    
    /**
     * 添加分类
     * @param category 分类信息
     * @return 分类ID
     */
    @Transactional(rollbackFor = Exception.class)
    public Long addCategory(BookCategory category) {
        // 检查分类名称是否重复
        if (bookCategoryMapper.selectOne(new LambdaQueryWrapper<BookCategory>()
                .eq(BookCategory::getName, category.getName())
                .eq(BookCategory::getParentId, category.getParentId())) != null) {
            throw new ServiceException("分类名称已存在");
        }
        
        // 检查父分类是否存在
        if (category.getParentId() != null) {
            if (bookCategoryMapper.selectById(category.getParentId()) == null) {
                throw new ServiceException("父分类不存在");
            }
        }
        
        // 设置默认排序号
        if (category.getSort() == null) {
            category.setSort(0);
        }
        
        if (bookCategoryMapper.insert(category) <= 0) {
            throw new ServiceException("添加分类失败");
        }
        
        return category.getId();
    }
    
    /**
     * 更新分类
     * @param id 分类ID
     * @param category 分类信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateCategory(Long id, BookCategory category) {
        // 检查分类是否存在
        if (bookCategoryMapper.selectById(id) == null) {
            throw new ServiceException("要更新的分类不存在");
        }
        
        // 检查分类名称是否与其他分类重复
        if (category.getName() != null) {
            BookCategory existCategory = bookCategoryMapper.selectOne(
                    new LambdaQueryWrapper<BookCategory>()
                    .eq(BookCategory::getName, category.getName())
                    .eq(BookCategory::getParentId, category.getParentId()));
            
            if (existCategory != null && !existCategory.getId().equals(id)) {
                throw new ServiceException("分类名称已被使用");
            }
        }
        
        // 检查父分类是否存在
        if (category.getParentId() != null) {
            if (bookCategoryMapper.selectById(category.getParentId()) == null) {
                throw new ServiceException("父分类不存在");
            }
            
            // 不能将分类的父级设置为自己或其子分类
            if (id.equals(category.getParentId()) || isChildCategory(id, category.getParentId())) {
                throw new ServiceException("不能将分类的父级设置为自己或其子分类");
            }
        }
        
        category.setId(id);
        
        if (bookCategoryMapper.updateById(category) <= 0) {
            throw new ServiceException("更新分类失败");
        }
    }
    
    /**
     * 判断一个分类是否是另一个分类的子分类
     * @param parentId 父分类ID
     * @param childId 子分类ID
     * @return 是否是子分类
     */
    private boolean isChildCategory(Long parentId, Long childId) {
        List<BookCategory> children = bookCategoryMapper.selectList(
                new LambdaQueryWrapper<BookCategory>()
                .eq(BookCategory::getParentId, parentId));
        
        for (BookCategory child : children) {
            if (child.getId().equals(childId) || isChildCategory(child.getId(), childId)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 删除分类
     * @param id 分类ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteCategory(Long id) {
        // 检查分类是否存在
        if (bookCategoryMapper.selectById(id) == null) {
            throw new ServiceException("要删除的分类不存在");
        }
        
        // 检查是否有子分类
        if (bookCategoryMapper.selectCount(new LambdaQueryWrapper<BookCategory>()
                .eq(BookCategory::getParentId, id)) > 0) {
            throw new ServiceException("该分类下有子分类，不能删除");
        }
        
        // 这里应该检查分类下是否有图书，如果有，则不能删除
        if(bookMapper.selectCount(new LambdaQueryWrapper<Book>().eq(Book::getCategoryId, id)) > 0) {
            throw new ServiceException("该分类下有图书，不能删除");
        }
        
        if (bookCategoryMapper.deleteById(id) <= 0) {
            throw new ServiceException("删除分类失败");
        }
    }
    
    /**
     * 根据ID获取分类
     * @param id 分类ID
     * @return 分类实体
     */
    public BookCategory getCategoryById(Long id) {
        BookCategory category = bookCategoryMapper.selectById(id);
        if (category == null) {
            throw new ServiceException("分类不存在");
        }
        return category;
    }
    
    /**
     * 获取有图书的分类并按照图书数量排序
     * @param limit 返回的分类数量限制，如果为null则返回所有
     * @return 分类列表，每个分类包含图书数量
     */
    public List<Map<String, Object>> getCategoriesWithBookCount(Integer limit) {
        // 查询所有分类
        List<BookCategory> allCategories = getAllCategories();
        
        // 用于存储分类ID和对应的图书数量
        List<Map<String, Object>> result = new ArrayList<>();
        
        for (BookCategory category : allCategories) {
            // 查询该分类下的图书数量
            long bookCount = bookMapper.selectCount(new LambdaQueryWrapper<Book>()
                    .eq(Book::getCategoryId, category.getId())
                    .eq(Book::getStatus, 1)); // 只统计上架的图书
            
            // 只添加有图书的分类
            if (bookCount > 0) {
                Map<String, Object> item = new HashMap<>();
                item.put("id", category.getId());
                item.put("name", category.getName());
                item.put("parentId", category.getParentId());
                item.put("bookCount", bookCount);
                result.add(item);
            }
        }
        
        // 按图书数量降序排序
        result.sort((a, b) -> Long.compare((Long)b.get("bookCount"), (Long)a.get("bookCount")));
        
        // 如果指定了数量限制，则截取指定数量
        if (limit != null && limit > 0 && limit < result.size()) {
            return result.subList(0, limit);
        }
        
        return result;
    }
} 